package Controllers

//  日志写入
import (
	"fmt"
	"github.com/gin-gonic/gin"
	"strconv"
	"strings"
	"unsafe"
)

func Remake(c *gin.Context) {

	//------------------------------Println 和 Print 的区别-------------------------------------------------
	// 第1个 Println 有换行，Print 没有
	fmt.Println("A")
	fmt.Print("B")

	// 第2个输出多个变量 Println 有空格，Print 没有空格
	fmt.Println("A", "A", "A")
	fmt.Print("B", "B", "B")

	//------------------------------Println 和 Printf 的区别-------------------------------------------------
	var a = "aaa"
	fmt.Println(a)                      // 正常输出
	fmt.Printf("%v\n", a)               // 支持格式化输出
	fmt.Printf("a = %v, a的类型是%T", a, a) // a 的类型

	// v=原样输出 ，d=10进制输出， b=二进制，o=八进制，x=16进制
	// f=浮点型值输出并保留6位小数 3.14159

	f := 3.1415926
	fmt.Printf("原值：%v,原值保留6位：%f, 保留俩位并四舍五入输出：%.2f", f, f, f)
	//------------------------------变量 严格区分大小写，大小写变量不是一个-------------------------------------------------
	age := 20
	Age := 22
	fmt.Println(age, Age) // 俩个变量不是同一个

	var name string // 	没有赋值的情况下是个空
	fmt.Println(name)

	// 初始化1
	var uname string
	uname = "张三"
	fmt.Println(uname)

	var uname2 string = "张三2"
	fmt.Println(uname2)

	var uname3 = "张三3"
	fmt.Println(uname3)

	// 一次声明多个变量
	var a1, a2 string
	var (
		aa1 string
		aa2 int
	)

	fmt.Println(a1, a2, aa1, aa2)

	// 多个申明变量 并且赋值
	var (
		b1 = "哈哈"
		b2 = 2
	)
	fmt.Println(b1, b2)

	// 短变量赋值
	c1, c2, c3 := 1, 2, 3
	fmt.Println(c1, c2, c3)

	d1, d2, d3 := 1, 2, "d3"
	fmt.Println(d1, d2, d3)

	//------------------------------常量-------------------------------------------------

	// 常量在定义的时候 必须要赋值，且无法修改
	const pr = 3.14

	const (
		A = 12
		B // 如果定义多个常量 且只给第一个赋值 后面的都是一样的
	)

	// 计数器
	const (
		C = iota
		_ // 跳过
		C2
		C3
	)

	fmt.Println(C, C2, C3) // 打印结果是 0-2-3

	// 插队
	const (
		N  = iota // 0
		N1 = 100  // 100
		N2 = iota // 2
		N3        // 3
	)

	fmt.Println(N, N1, N2, N3) // 打印结果是 0-100-2-3

	// iota 多变量在一列 【只要每一行出现iota 就是+1】
	const (
		M, MM  = iota + 1, iota + 2 // 1,2
		M2, M3                      // 2,3
		M4, M5                      // 3,4
	)

	//------------------------------查看内存中变量所占的大小-------------------------------------------------

	var sizeof int8 = 12
	fmt.Printf("%v %T \n", sizeof)     // 12 int8
	fmt.Println(unsafe.Sizeof(sizeof)) // 结果 1，表示一个字节
	//unsafe.Sizeof 无法获取字符串的存储空间大小

	//------------------------------强制转换类型-------------------------------------------------
	var i1 int32 = 12
	var i2 int64 = 32
	fmt.Println(int64(i1)) // 32 强转64位
	fmt.Println(int32(i2)) // 64转32

	// 高位转低位 可能造成内存益处
	var it1 int16 = 138
	fmt.Println(int8(it1)) // 可以转 但是转出去的结果会变成-126 就会造成放不下的问题

	// int 转float
	ab := 12
	abf := float64(ab)
	fmt.Println(abf)

	// float转int
	//var c11 float32 = 25.24
	// 若是浮点和整形相加 要把整形转成浮点，不能浮点转整形 因为浮点会舍弃小数点后面的数
	c11 := 25.24
	c22 := int(c11)
	fmt.Printf("c2的值 %v, c2的类型 %T", c22, c22) // 会把小数点后面的额直接截取调 这里等于 25

	// 布尔类型 只能是true和false 不能像PHP那样 1=true 0=flase
	var bb bool
	fmt.Println(bb) // 默认是false

	var ss string
	fmt.Println(ss) // 默认是空

	var ii int
	fmt.Println(ii) // 默认是0 和浮点型 一样

	//------------------------------string-------------------------------------------------
	//len() 获取字符串长度

	// 拼接字符串 + 或者 fmt。spintf
	// Sprintf 表示获取里面的值 并赋值给一个新的变量

	str1 := "hhh"
	str2 := "ppp"
	str3 := fmt.Sprintf("%v %v", str1, str2)
	fmt.Println(str2 + str1)
	fmt.Println(str3)

	ccstr := "dddddd" + "jjjjjj" + "lllll"
	fmt.Printf("%v \n", ccstr)

	// 字符串转数组 strings.split
	str4 := "213-nbjh8-98hj"
	arr := strings.Split(str4, "-")
	fmt.Println(arr) // 切片

	// 字符串转数组 strings.join 【整形切片 无法转字符串】
	//arr12 := []int{1, 2, 3, 4}
	arr12 := []string{"php", "java", "go"}
	str5 := strings.Join(arr12, "-")
	fmt.Println(str5) // 切片

	// 字符串是否包含 strings.Contains
	str6 := "lk opop iijuh hhh"
	str7 := "hh"
	flag1 := strings.Contains(str6, str7)
	fmt.Println(flag1) //  返回true

	// 字符串前缀 strings.Contains
	str8 := "lk opop iijuh hhh"
	str9 := "hh"
	flag2 := strings.HasPrefix(str8, str9) // 前缀
	flag3 := strings.HasSuffix(str8, str9) // 后缀
	fmt.Println(flag2)                     //  返回true
	fmt.Println(flag3)                     //  返回true

	// 字符串出现的位置 strings.index
	str10 := "lk hhh"
	str11 := "hh"
	num := strings.Index(str10, str11)
	num2 := strings.LastIndex(str10, str11)
	fmt.Println(num)  //   返回 3, 查第一次出现的位置
	fmt.Println(num2) //   返回 4, 查最后 一次出现的位置

	//------------------------------字符-------------------------------------------------
	var z1 = "this"
	fmt.Printf("%v %T \n", z1[2], z1[2]) //
	fmt.Printf("%c \n", z1[2])           // 原样输出字符

	z2 := "你好 goland"
	//for i:=0;i<len(z2);i++{	// byte
	//	fmt.Printf("%v %T \n", z2[i], z2[i])     // 有中文的 不能使用len 这种循环
	//}
	for _, v := range z2 { // rune
		fmt.Printf("%v %T \n", v, v) // 有中文的 可以使用range循环
	}

	for _, v := range z2 {
		fmt.Printf("%c \n", v) // %c 将打印每个 Unicode 字符的字符形式。 可以输出中文
	}
	// 字符串里面的字符转换【 】
	// 如果是没有中文的 可以先转成byte 再转成字符串
	str12 := "big"
	//str12[0] = 'p'	// 错误
	byteStr := []byte(str12)
	byteStr[0] = 'p'
	fmt.Println(string(byteStr)) // 输出 “pig”

	// 如果是没有中文的 可以先转成rune [如呢]
	str13 := "哈喽 go"
	runeStr := []rune(str13)
	runeStr[0] = '哦'
	fmt.Println(string(runeStr)) // 输出 “哦喽 go”

	//------------------------------类型转换-------------------------------------------------

	var it11 int = 12
	var fl1 float32 = 32.222
	var bl bool = true
	var byt byte = 'a'

	// 通过 Sprintf 转字符串
	strz1 := fmt.Sprintf("%d", it11) // 转成十进制 并赋值新变量
	fmt.Println(strz1)               // 输出 "12"

	strz2 := fmt.Sprintf("%f", fl1) //
	fmt.Println(strz2)              // 输出 "32.222"

	strz3 := fmt.Sprintf("%t", bl) //
	fmt.Println(strz3)             // 输出 "true"

	strz4 := fmt.Sprintf("%c", byt) // c 原样输出字符
	fmt.Println(strz4)              // 输出 "true"

	// 通过第三方包转换
	zstr := strconv.FormatInt(int64(it11), 10)             // 第一个参数要转的 第二个参数是进制
	fmt.Println(zstr)                                      // 输出 "12"
	zstr2 := strconv.FormatFloat(float64(fl1), 'f', 4, 64) //  浮点转字符串 1、要转的 2、基本默认参数 3、保留小数点 4、转出格式
	fmt.Println(zstr2)

	//zstr3 := strconv.FormatBool(bl) //  没有意义
	//zstr4 := strconv.FormatUint(uint64(byt), 10) //  没有意义

	// 字符串转int float
	str14 := "132456"
	num3, err := strconv.ParseInt(str14, 10, 64) // 1需要转的字符串 2转出申明进制 3转出位数
	//num4, err2 := strconv.ParseFloat(str14, 64)  // 1需要转的字符串 3转出位数
	if err != nil {
		fmt.Println("转换失败")
	}
	fmt.Println(num3)

	//var ii int8 = 12
	//var ia int
	//ia++
	//ii--	// 错误
	//ia = ii++	//	错误 go中 ++ -- 不能赋值，只能单独写
	//++ia
	//--ia	不能放在前面

	// 俩个变量的值互换
	hh1 := 12
	var hh2 int = 21
	var tmp int = hh1
	hh2 = tmp
	hh1 = hh2

	// 不能使用中间变量 互换
	hhh1 := 12
	hhh2 := 21
	hhh1 = hhh1 + hhh2 // 俩数的和
	hhh2 = hhh1 - hhh2 // 和 - 21 = 12【a的值】
	hhh1 = hhh1 - hhh2 // 和 - 12 = 21【b的值】

	// 温度转换、
	var F float64 = 100
	var gd float64 = 32
	CC := (F - gd) / 1.8
	fmt.Printf("摄氏温度为 %.2f:", CC)

	// 位运算符  只针对整数在二进制中的操作
	var wa = 5            // 二进制 = 101
	var wa2 = 2           // 二进制 = 010
	fmt.Println(wa & wa2) // 比较的是二进制的值 与 对俩个二进制的数的每一位比较如果都是1 才是1
	fmt.Println(wa | wa2) // 比较的是二进制的值 或 对俩个二进制的数的每一位比较只要有一个是1 就是1
	fmt.Println(wa ^ wa2) // 比较的是二进制的值 异或 对俩个二进制的数的每一位比较每一个不一样 就是1

	//------------------------------IF----------------- --------------------------------
	//if age := 30; age > 36 {
	//	fmt.Println("局部年龄", age)
	//}
	//fmt.Println("外部年龄", age)		报错 age在if体内 只属于 if

	// 打印结果
	/**
	三行四列
	****
	****
	****
	*/
	row := 3
	col := 4
	for i := 1; i <= row; i++ {
		for j := 1; j <= col; j++ {
			fmt.Println("*")
		}
	}

	// 乘法表
	for ix := 1; ix <= 9; ix++ {
		for jx := 1; jx <= ix; jx++ {
			fmt.Printf("%v * %v = %v", ix, jx, ix*jx)
		}
	}

	//------------------------------lable----------------- --------------------------------

lable3:
	for i := 0; i < 2; i++ {
		for j := 0; j < 10; j++ {

			if j == 3 {
				continue lable3
			}
			fmt.Printf("i=%v,j=%v\n", i, j)

		}
	}

	// 结果
	/**
	i=0,j=0
	i=0,j=1
	i=0,j=2
	i=1,j=0
	i=1,j=1
	i=1,j=2
	*/

	//------------------------------goto----------------- --------------------------------
	// 直接跳转到 lable去执行下面的代码 好用
	gt := 5
	if gt > 3 {
		fmt.Println("aa")
		goto lable4
	}

	fmt.Println("bb")
lable4:
	fmt.Println("cc")

}
